/****
 * Copyright (C) 2006 dNux Team
 *                                                            ****
 * This program is free software; you can redistribute it and/or *
 * modify under the terms of the GNU General Public License as   *
 * published by the Free Software Foundation;                    *
 * either version 2 of the License.                              *
 *                                                               *
 * This program is distributed in the hope that it will be       *
 * useful, but WITHOUT ANY WARRANTY; without even the implied    *
 * warranty of without even the implied waranty of               *
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.          *
 * See the GNU General Public License for more details.          *
 *                                                               *
 * You should have received a copy of the                        *
 * GNU General Public License                                    *
 * along with this program; if not, write to the                 *
 * Free Software Foundation, Inc.,                               *
 * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA. *
 *                                                               *
 ****                                                         ****/

void
map_del(d_check_t *check)
{
  int a=12, b=13;
  int *c;

  d_map_t *map=NULL;
  d_map_iterator_t *it=NULL;
  d_map_data_t *data=NULL;

  map = d_map_new();
  d_map_pushback(map, d_map_data_new("a", &a, NULL));
  d_map_pushback(map, d_map_data_new("b", &b, NULL));

  it = d_map_begin(map);
  d_map_del(it);
  d_map_free_iterator(&it);

  it = d_map_begin(map);
  d_map_data(it, &data);
  c = (int *) data->value;
  if (*c == 13) {
    d_check_add(check, D_CHECK_OK, "map::del => work as expected.");
  } else {
    d_check_add(check, D_CHECK_ERROR, "map::del => doesn't work has expected.");
  }
  d_map_free_iterator(&it);
  d_map_free(&map);

}


void
map_begin(d_check_t *check)
{
  int a=13, b=12;
  int *c;

  d_map_t *map=NULL;
  d_map_iterator_t *it=NULL;
  d_map_data_t *data=NULL;

  map = d_map_new();
  it = d_map_begin(map);
  if (it) {
    d_check_add(check, D_CHECK_ERROR, "map::begin => it should be null here.");
    d_map_free_iterator(&it);
    goto error;
  }

  d_map_pushback(map, d_map_data_new("a", &a, NULL));
  d_map_pushback(map, d_map_data_new("b", &b, NULL));
  it = d_map_begin(map);
  if (!it) {
    d_check_add(check, D_CHECK_ERROR, "map::begin => it should'nt be null here.");
    goto error;
  }

  d_map_data(it, &data);
  c = (int *) data->value;
  if (*c == a) {
    d_check_add(check, D_CHECK_OK, "map::begin => point on the good element.");
  } else {
    d_check_add(check, D_CHECK_ERROR, "map::begin => should'nt point here.");
  }

  d_map_free_iterator(&it);

 error:
  d_map_free(&map);
  return;
}


void map_new(d_check_t *check)
{
  d_map_t *map=NULL;
  map = d_map_new();
  if (map != NULL) {
    d_check_add(check, D_CHECK_OK, "map::new => map created");
    d_map_free(&map);
  }
  else {
    d_check_add(check, D_CHECK_ERROR, "map::new => map can't be created.");
  }
}


void
map_push(d_check_t *check)
{
  int a=9, b=12;
  int *c=NULL;
  d_map_t *map=NULL;
  d_map_iterator_t *it=NULL;
  d_map_data_t *data=NULL;

  map = d_map_new();

  d_map_push(map, d_map_data_new("a", &a, NULL));
  d_map_push(map, d_map_data_new("b", &b, NULL));
  
  it = d_map_begin(map);
  d_map_data(it, &data);
  c = (int *) data->value;
  if (*c == b) {
    d_map_next(&it);
    d_map_data(it, &data);
    c = (int *) data->value;
    if (*c == a) {
      d_check_add(check, D_CHECK_OK, "map::push => data order is ok.");
    }
    else {
      d_check_add(check, D_CHECK_ERROR, "map::push => value not excepted.");
    }
  }
  else {
    d_check_add(check, D_CHECK_ERROR, "map::push => value not excepted.");
  }
  d_map_free_iterator(&it);

  d_map_free(&map);
}

d_bool_t map_free_func_ok;

void
map_free_func(void *data)
{
  map_free_func_ok = d_true;
}

void
map_data_free_func(d_check_t *check)
{
  int a=12;
  d_map_t *map=NULL;

  map_free_func_ok = d_false;

  map = d_map_new();
  d_map_push(map, d_map_data_new("a", &a, map_free_func));
  d_map_free(&map);

  if (map_free_func_ok) {
    d_check_add(check, D_CHECK_OK, "map::data_free_func => was called.");
  } else {
    d_check_add(check, D_CHECK_ERROR, "map::data_free_func => was'nt called.");
  }
}

void
map_free_iterator(d_check_t *check)
{
  int a=12;
  d_map_t *map=NULL;
  d_map_iterator_t *it=NULL;


  map = d_map_new();
  d_map_push(map, d_map_data_new("a", &a, NULL));

  it = d_map_begin(map);
  if (! it) {
    d_check_add(check, D_CHECK_ERROR, "map::free_iterator => d_map_begin doen't work.");
  } else {
    d_map_free_iterator(&it);
    if (it) {
      d_check_add(check, D_CHECK_ERROR, "map::free_iterator => it not NULL.");
    } else {
      d_check_add(check, D_CHECK_OK, "map::free_iterator => it is NULL.");
    }
  }
  d_map_free(&map);
}


void
map_clear(d_check_t *check)
{
  int a=12;

  d_map_t *map=NULL;

  map = d_map_new();
  d_map_push(map, d_map_data_new("a", &a, NULL));
  d_map_clear(map);
  if (d_map_length(map) == 0) {
    d_check_add(check, D_CHECK_OK, "map::clear => map is clear");
  } else {
    d_check_add(check, D_CHECK_ERROR, "map::clear => map is not clear");
  }
  d_map_free(&map);
}


void
map_prev(d_check_t *check)
{
  int a=12, b=13, c=14;
  int *d;

  d_map_t *map=NULL;
  d_map_iterator_t *it=NULL;
  d_map_data_t *data=NULL;

  map = d_map_new();
  d_map_pushback(map, d_map_data_new("a", &a, NULL));
  d_map_pushback(map, d_map_data_new("b", &b, NULL));
  d_map_pushback(map, d_map_data_new("c", &c, NULL));
  
  it = d_map_end(map);
  d_map_prev(&it);
  d_map_data(it, &data);
  d = (int *) data->value;
  if (*d != b) {
    d_check_add(check, D_CHECK_ERROR, "map::prev => it should have b value.");
    d_map_free_iterator(&it);
    goto error;
  }
  d_map_prev(&it);
  d_map_data(it, &data);
  d = (int *) data->value;
  d_map_free_iterator(&it);
  if (*d != a) {
    d_check_add(check, D_CHECK_ERROR, "map::prev => it should hava a value.");
    goto error;
  }

  d_check_add(check, D_CHECK_OK, "map::prev => tested.");

 error:
  d_map_free(&map);
}


void
map_length(d_check_t *check)
{
  int a=12, b=13, c=14;
  d_map_t *map=NULL;

  map = d_map_new();

  if (d_map_length(map) != 0) {
    d_check_add(check, D_CHECK_ERROR, "map::length => should be 0 here.");
    goto error;
  }

  d_map_push(map, d_map_data_new("a", &a, NULL));
  if (d_map_length(map) != 1) {
    d_check_add(check, D_CHECK_ERROR, "map::length => should be 1 here.");
    goto error;
  }

  d_map_pushback(map, d_map_data_new("b", &b, NULL));
  d_map_pushback(map, d_map_data_new("c", &c, NULL));
  if (d_map_length(map) != 3) {
    d_check_add(check, D_CHECK_ERROR, "map::length => should be 3 here.");
    goto error;
  }

  d_check_add(check, D_CHECK_OK, "map::length => tested.");
 error:
  d_map_free(&map);
  return;
}


void
map_iterator_valid(d_check_t *check)
{
  int a=12, b=13;

  d_map_t *map=NULL;
  d_map_iterator_t *it=NULL;

  map = d_map_new();
  d_map_pushback(map, d_map_data_new("a", &a, NULL));
  d_map_pushback(map, d_map_data_new("b", &b, NULL));

  it = d_map_begin(map);
  if (! d_map_iterator_valid(it)) {
    d_check_add(check, D_CHECK_ERROR, "map::iterator_valid => it should be valid here.");
    goto error;
  }

  d_map_next(&it);
  if (! d_map_iterator_valid(it)) {
    d_check_add(check, D_CHECK_ERROR, "map::iterator_valid => it should be valid here.");
    goto error;
  }

  d_map_next(&it);
  if (d_map_iterator_valid(it)) {
    d_check_add(check, D_CHECK_ERROR, "map::iterator_valid => it should'nt be valid here.");
    goto error;
  }

  d_check_add(check, D_CHECK_OK, "map::iterator_valid => tested.");

 error:
  d_map_free_iterator(&it);
  d_map_free(&map);
  return;
}


void
map_free(d_check_t *check)
{
  d_map_t *map=NULL;
  map = d_map_new();
  if (map) {
    d_map_free(&map);
    if (! map) {
      d_check_add(check, D_CHECK_OK, "map::free => map created & free as except.");
    } else {
      d_check_add(check, D_CHECK_ERROR, "map::free => map created but not free.");
    }
  } else {
    d_check_add(check, D_CHECK_ERROR, "map::free => map can't be created.");
  }
}


void
map_at(d_check_t *check)
{
  int a=2, b=3, c=4;
  int *d=NULL;

  d_map_t *map=NULL;
  d_map_iterator_t *it=NULL;
  d_map_data_t *data;

  map = d_map_new();
  d_map_push(map, d_map_data_new("a", &a, NULL));
  d_map_push(map, d_map_data_new("b", &b, NULL));
  d_map_push(map, d_map_data_new("c", &c, NULL));

  it = d_map_at(map, 75);
  if (it) {
    d_check_add(check, D_CHECK_ERROR, "map::at => it should be NULL here.");
    d_map_free_iterator(&it);
    goto error;
  }

  it = d_map_at(map, 1);
  d_map_data(it, &data);
  d_map_free_iterator(&it);
  d = (int *) data->value;
  if (*d != b) {
    d_check_add(check, D_CHECK_ERROR, "map::at => it should have b value.");
    goto error;
  }
  
  it = d_map_at(map, 2);
  d_map_data(it, &data);
  d_map_free_iterator(&it);
  d = (int *) data->value;
  if (*d != a) {
    d_check_add(check, D_CHECK_ERROR, "map::at => it should have a value.");
  }

  d_check_add(check, D_CHECK_OK, "map::at => verified.");
 error:
  d_map_free(&map);
  return;
}


void
map_pushback(d_check_t *check)
{
  int a=9, b=12;
  int *c=NULL;
  d_map_t *map=NULL;
  d_map_iterator_t *it=NULL;
  d_map_data_t *data=NULL;

  map = d_map_new();

  d_map_pushback(map, d_map_data_new("a", &a, NULL));
  d_map_pushback(map, d_map_data_new("b", &b, NULL));
  
  it = d_map_begin(map);
  d_map_data(it, &data);
  c = (int *) data->value;
  if (*c == a) {
    d_map_next(&it);
    d_map_data(it, &data);
    c = (int *) data->value;
    if (*c == b) {
      d_check_add(check, D_CHECK_OK, "map::pushback => data order is ok.");
    }
    else {
      d_check_add(check, D_CHECK_ERROR, "map::pushback => value not excepted.");
    }
  }
  else {
    d_check_add(check, D_CHECK_ERROR, "map::pushback => value not excepted.");
  }
  d_map_free_iterator(&it);

  d_map_free(&map);
}


void
map_next(d_check_t *check)
{
  int a=12, b=13, c=14;
  int *d;

  d_map_t *map=NULL;
  d_map_iterator_t *it=NULL;
  d_map_data_t *data=NULL;

  map = d_map_new();
  d_map_pushback(map, d_map_data_new("a", &a, NULL));
  d_map_pushback(map, d_map_data_new("b", &b, NULL));
  d_map_pushback(map, d_map_data_new("c", &c, NULL));
  
  it = d_map_begin(map);
  d_map_next(&it);
  d_map_data(it, &data);
  d = (int *) data->value;
  if (*d != b) {
    d_check_add(check, D_CHECK_ERROR, "map::next => it should have b value.");
    d_map_free_iterator(&it);
    goto error;
  }
  d_map_next(&it);
  d_map_data(it, &data);
  d = (int *) data->value;
  d_map_free_iterator(&it);
  if (*d != c) {
    d_check_add(check, D_CHECK_ERROR, "map::next => it should hava c value.");
    goto error;
  }

  d_check_add(check, D_CHECK_OK, "map::next => tested.");

 error:
  d_map_free(&map);
}


void
map_end(d_check_t *check)
{
  int a=13, b=12;
  int *c;
  d_map_t *map=NULL;
  d_map_iterator_t *it=NULL;
  d_map_data_t *data=NULL;

  map = d_map_new();
  it = d_map_end(map);
  if (it) {
    d_check_add(check, D_CHECK_ERROR, "map::end => it should be null here.");
    d_map_free_iterator(&it);
    goto error;
  }

  d_map_pushback(map, d_map_data_new("a", &a, NULL));
  d_map_pushback(map, d_map_data_new("b", &b, NULL));
  it = d_map_end(map);
  if (!it) {
    d_check_add(check, D_CHECK_ERROR, "map::end => it should'nt be null here.");
    goto error;
  }

  d_map_data(it, &data);
  c = (int *) data->value;
  if (*c == b) {
    d_check_add(check, D_CHECK_OK, "map::end => point on the good element.");
  } else {
    d_check_add(check, D_CHECK_ERROR, "map::end => should'nt point here.");
  }

  d_map_free_iterator(&it);

 error:
  d_map_free(&map);
  return;
}


void
map_data(d_check_t *check)
{
  int a=12;
  int *b;

  d_map_t *map=NULL;
  d_map_iterator_t *it=NULL;
  d_map_data_t *data=NULL;

  map = d_map_new();
  d_map_push(map, d_map_data_new("a", &a, NULL));

  it = d_map_begin(map);
  d_map_data(it, &data);
  b = (int *) data->value;
  if (strcmp(data->key, "a")) {
    d_check_add(check, D_CHECK_ERROR, "map::data => key incorrect.");
  } else {
    if (*b == a) {
      d_check_add(check, D_CHECK_OK, "map::data => is okay !");
    } else {
      d_check_add(check, D_CHECK_ERROR, "map::data => value is incorrect");
    }
  }
  d_map_free_iterator(&it);
  d_map_free(&map);
}

void
map_tests(d_check_t *check)
{
  fprintf(stdout, ">> map_tests <<\n");
  map_at(check);
  map_begin(check);
  map_clear(check);
  map_del(check);
  map_end(check);
  map_free(check);
  map_data_free_func(check);
  map_free_iterator(check);
  map_iterator_valid(check);
  map_length(check);
  map_new(check);
  map_next(check);
  map_prev(check);
  map_pushback(check);
  map_push(check);
  map_data(check);
  fprintf(stdout, "\n");
}


